/**
 *      C++ 的基础：
 *          （1）、引用
 *          （2）、引用与指针
 *          （3）、C++中结构体，与C语言中结构体的差异 
 * 
 **/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>


int addResut(int &a, int &b)
{
    ++a;
    ++b;
    return a+b;
}

int addResult1(int *a, int *b)
{
    ++(*a);
    ++(*b);
    return *a+*b;
}

void createInt(int **p)
{
    // new 就像是一个 “内存采购助手”，专门帮你从计算机的内存 “仓库” 中获取存储数据的空间，
    // 这里需要代码编写者自己维护这块内存，如果反复申请，不去释放，就会造成内存的不可控即“内存泄漏”
    *p = new int(4);
}

void createInt1(int*& p)
{
    p = new int(8);
}

int main()
{
    {   
        // 引用
        int num = 10;
        int& ref_num = num; // 引用时必须要赋值，如int& ref_num; 这样就是错误的使用方式
        ref_num = 20;
        printf("num = %d, ref_num = %d\n", num, ref_num);   // 这里两个值均发生改变
        // int&& ref_refNum = num;  错误
    
        int a = 4, b = 8;
        int ret = addResut(a, b);
        printf("a = %d, b = %d, ret = %d\n", a, b, ret);   // 这里a, b两个值均发生改变
    
        int ret1 = addResult1(&a, &b);
        
        printf("a = %d, b = %d, ret1 = %d\n", a, b, ret1);   // 这里a, b两个值均发生改变

        int *p = nullptr;
        createInt(&p);                  // 这里指针作为变量，用于创建一个int对象
        printf("*p = %d\n", *p);   

        int *p1 = nullptr;
        createInt1(p1);                 // 这里传引用，指针作为一个变量，引用为这块内存的别名。
        printf("*p1 = %d\n", *p1);  

        // delete:与new是一对一使用的，delete 来 “归还” 给内存 “仓库”
        delete p;
        p = nullptr;
        delete p1;
        p1 = p1;
    }

    {
        // 结构体
        struct Student {
            char name[20];
            int age;
            float score;
            Student(){}
            Student(char* pNm, int iAge, float fScore)
            {
                strcpy(name, pNm);
                age = iAge;
                score = fScore;
            }
            void printInfo() {
                std::cout << "姓名: " << name << ", 年龄: " << age << ", 成绩: " << score << std::endl;
            }
        };

        // 与C语言类似的使用方式
        struct Student stu;
        strcpy(stu.name, "李四");
        stu.age = 19;
        stu.score = 90.0;
        stu.printInfo();

        struct Student stu1("Tom", 18, 99.5);
        stu1.printInfo();
    }

    return 0;
}